using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SeataNet.Core.AT;
using SeataNet.Core.TCC;
using System.Data.Common;

namespace SeataNet.Samples.OrderService.Controllers
{
    /// <summary>
    /// 订单服务控制器
    /// 演示 Seata .NET 与 Java Seata 的兼容性使用
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class OrderController : ControllerBase
    {
        private readonly ILogger<OrderController> _logger;
        private readonly IAtDataSourceProxy _dataSource;
        private readonly IHttpClientFactory _httpClientFactory;

        public OrderController(
            ILogger<OrderController> logger,
            IAtDataSourceProxy dataSource,
            IHttpClientFactory httpClientFactory)
        {
            _logger = logger;
            _dataSource = dataSource;
            _httpClientFactory = httpClientFactory;
        }

        /// <summary>
        /// 创建订单 - AT 模式示例
        /// 对应 Java: @GlobalTransactional
        /// </summary>
        [HttpPost("create")]
        [GlobalTransactional(
            Name = "create-order-transaction",
            Timeout = 60000,
            Propagation = TransactionPropagationBehavior.Required,
            RollbackFor = new[] { typeof(Exception) }
        )]
        public async Task<IActionResult> CreateOrder([FromBody] CreateOrderRequest request)
        {
            _logger.LogInformation("开始创建订单，订单号：{OrderId}", request.OrderId);

            try
            {
                // 1. 创建订单记录（本地数据库操作）
                await CreateOrderRecord(request);

                // 2. 调用库存服务扣减库存（Java 微服务）
                await DeductStock(request.ProductId, request.Quantity);

                // 3. 调用账户服务扣款（.NET 微服务）
                await DeductBalance(request.UserId, request.TotalAmount);

                _logger.LogInformation("订单创建成功，订单号：{OrderId}", request.OrderId);
                return Ok(new { Success = true, OrderId = request.OrderId });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建订单失败，订单号：{OrderId}", request.OrderId);
                throw; // 自动触发全局事务回滚
            }
        }

        /// <summary>
        /// 本地数据库操作 - 使用 AT 数据源代理
        /// </summary>
        private async Task CreateOrderRecord(CreateOrderRequest request)
        {
            // 使用 AT 数据源代理创建连接
            // 对应 Java: DataSourceProxy
            using var connection = _dataSource.CreateConnection();
            await connection.OpenAsync();

            using var command = connection.CreateCommand();
            command.CommandText = @"
                INSERT INTO orders (order_id, user_id, product_id, quantity, total_amount, status, create_time)
                VALUES (@orderId, @userId, @productId, @quantity, @totalAmount, @status, @createTime)";

            AddParameter(command, "@orderId", request.OrderId);
            AddParameter(command, "@userId", request.UserId);
            AddParameter(command, "@productId", request.ProductId);
            AddParameter(command, "@quantity", request.Quantity);
            AddParameter(command, "@totalAmount", request.TotalAmount);
            AddParameter(command, "@status", "PENDING");
            AddParameter(command, "@createTime", DateTime.UtcNow);

            await command.ExecuteNonQueryAsync();
            _logger.LogDebug("订单记录已创建：{OrderId}", request.OrderId);
        }

        /// <summary>
        /// 调用 Java 微服务 - 库存服务
        /// </summary>
        private async Task DeductStock(string productId, int quantity)
        {
            var httpClient = _httpClientFactory.CreateClient();

            // 调用 Java Spring Cloud 库存服务
            var stockRequest = new
            {
                ProductId = productId,
                Quantity = quantity
            };

            var response = await httpClient.PostAsJsonAsync(
                "http://stock-service/api/stock/deduct",
                stockRequest);

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception($"库存扣减失败：{await response.Content.ReadAsStringAsync()}");
            }

            _logger.LogDebug("库存扣减成功：ProductId={ProductId}, Quantity={Quantity}",
                productId, quantity);
        }

        /// <summary>
        /// 调用 .NET 微服务 - 账户服务
        /// </summary>
        private async Task DeductBalance(string userId, decimal amount)
        {
            var httpClient = _httpClientFactory.CreateClient();

            // 调用 .NET 账户服务
            var accountRequest = new
            {
                UserId = userId,
                Amount = amount
            };

            var response = await httpClient.PostAsJsonAsync(
                "http://account-service/api/account/deduct",
                accountRequest);

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception($"账户扣款失败：{await response.Content.ReadAsStringAsync()}");
            }

            _logger.LogDebug("账户扣款成功：UserId={UserId}, Amount={Amount}", userId, amount);
        }

        private void AddParameter(DbCommand command, string name, object value)
        {
            var parameter = command.CreateParameter();
            parameter.ParameterName = name;
            parameter.Value = value ?? DBNull.Value;
            command.Parameters.Add(parameter);
        }
    }

    /// <summary>
    /// 创建订单请求
    /// </summary>
    public class CreateOrderRequest
    {
        public string OrderId { get; set; } = string.Empty;
        public string UserId { get; set; } = string.Empty;
        public string ProductId { get; set; } = string.Empty;
        public int Quantity { get; set; }
        public decimal TotalAmount { get; set; }
    }
}
